"use strict";
/*
K =  696e737069726564

*/
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.to2 = void 0;
const DES_1 = require("./DES");
const DES_2 = require("./DES");
const fs_1 = __importDefault(require("fs"));
// 未知的比特个数 7 的倍数，e.g：7 14 21 28
const SIZE = 21;
const fillCheckBitNumber = '1';
const K = '696e737069726564';
// 已知的前N个bit数
const knownK = K.substring(0, K.length - (SIZE / 7 * 2));
// 
const KBinary = (0, DES_1.getBinary)(knownK);
// 密文，解密后的明文：positive
const ciphertext = 'f6daa309a4e78f39';
/**
 * 开始解密
 */
function start() {
    const startTimestamp = Date.now();
    createHypothesisKey(0, 2 ** SIZE - 1);
    const endTimestamp = Date.now();
    console.log(`总用时间：${endTimestamp - startTimestamp}ms`);
    const re = `耗时：${endTimestamp - startTimestamp}ms，校验位使用：方案${fillCheckBitNumber},计算总个数：${2 ** SIZE - 1}`;
    fs_1.default.writeFileSync(`./recode/${SIZE}_${fillCheckBitNumber}_data.txt`, JSON.stringify(re));
}
function createHypothesisKey(beginPos, endPos) {
    const arr = [];
    for (let index = beginPos; index <= endPos; index++) {
        printTip(`进行第${index + 1}次`);
        const startTimestamp = Date.now();
        printTip(`构建猜想密钥中...`);
        let b = to2(index); // 返回7位二进制
        // b = fillCheckBit1(b) // 方案1，补校验位
        if (fillCheckBitNumber === '1') {
            b = fillCheckBit1(b); // 方案1，补校验位
        }
        else {
            b = fillCheckBit2(b); // 方案2，补校验位
        }
        const hypothesisKey = KBinary + b;
        printTip(`构建猜想密钥完成：${hypothesisKey}`);
        // 子密钥组
        const subkeyArr = (0, DES_2.subkeyconstructioner)(hypothesisKey);
        // 解密结果
        printTip(`解密中`);
        const result = (0, DES_2.decrypter)(ciphertext, subkeyArr);
        printTip(`解密结束，机密后的内容：${result}`);
        // 校验
        printTip(`校验中`);
        const verify = textVerify(result);
        printTip(`校验结果: ${verify}`);
        const endTimestamp = Date.now();
        const spendTime = endTimestamp - startTimestamp;
        arr.push({
            number: index + 1,
            hypothesisKey,
            result,
            verify,
            spendTime,
        });
    }
    printTip('写入文件');
    fs_1.default.writeFileSync(`./recode/${SIZE}_${fillCheckBitNumber}_data.json`, JSON.stringify(arr));
    printTip('写入完成');
    return arr;
}
/**
 * 对解密后得内容进行 明文校验
 * @param text 解密后的内容
 * @returns 正确 true, 错误 false
 */
function textVerify(text) {
    const regExp = /^[1-9a-zA-Z?!:';.,]*$/g;
    const result = text.match(regExp);
    return result !== null ? true : false;
}
function printTip(str) {
    console.log(`----------- ${str} -----------`);
}
/**
 * 填充校验位，方案1，直接补0
 * @param binary
 * @returns
 */
function fillCheckBit1(binary) {
    let result = '';
    for (let i = 0; i < binary.length / 7; i++) {
        let value = binary.substring(i * 7, (1 + i) * 7);
        result += value + '0';
    }
    return result;
}
/**
 * 填充校验位，方案2。奇数个1补0，偶数个1补1
 * @param binary
 * @returns
 */
function fillCheckBit2(binary) {
    const obj = {};
    for (let i = 0; i < binary.length; i++) {
        const value = binary.substring(i, i + 1);
        // @ts-ignore
        if (obj[value]) {
            // @ts-ignore
            obj[value]++;
        }
        else {
            // @ts-ignore
            obj[value] = 1;
        }
    }
    // @ts-ignore
    if (obj['1'] % 2 === 0) {
        return binary + '1';
    }
    else {
        return binary + '0';
    }
}
/**
 * 这个方法是提供给 to2 的
 * @param num
 * @deprecated 不要使用，使用 to2 方法
 * @returns
 */
function DecimalTransformBinary(num) {
    if (num === 0 || num === 1)
        return num + '';
    // 余数
    const remainder = num % 2 + '';
    const result = Math.floor(num / 2);
    return DecimalTransformBinary(result) + remainder;
}
/**
 * 一个 10 进制 转 2进制
 * @param num
 * @returns
 */
function to2(num) {
    let result = DecimalTransformBinary(num);
    const zeros = '0000000000000000000000000000000000000000000000000000000000000000';
    const shortNum = SIZE - result.length;
    result = zeros.substring(0, shortNum) + result;
    return result;
}
exports.to2 = to2;
start();
